package main

import "fmt"

type Phone interface {
	call()
}

type AndroidPhone struct {
	name string
}
type Iphone struct {
	name string
}

type ISayHello interface {
	sayHello()
}
type Duck struct {
	name string
}
type Person1 struct {
	name string
}

type Income interface {
	printProjectName() string
	calculate() float64
}

type TimeProject struct {
	projectName string
	amount      float64
}
type FixProject struct {
	projectName string
	amount      float64
}

type Shape interface {
	area() float64
}

type Juxing struct {
	chang, kuan float64
}

type Yuanxing struct {
	banjing float64
}

func main() {
	phone := new(AndroidPhone)
	phone.call()
	phone1 := AndroidPhone{"安卓"}
	phone1.call()
	var phone2 Phone = Iphone{"苹果"}
	phone2.call()

	//duck typing
	duck := Duck{"鸭子"}
	person1 := Person1{"万祥"}
	duck.sayHello()
	person1.sayHello()
	var inter ISayHello = duck
	inter.sayHello()
	//切换实现
	inter = person1
	inter.sayHello()

	//多态
	p1 := FixProject{"固定项目1", 1000}
	p2 := FixProject{"固定项目2", 2000}
	p3 := TimeProject{"时间项目1", 1000}
	p4 := TimeProject{"时间项目2", 2000}
	incomeArray := []Income{p1, p2, p3, p4}
	totalAmount := calculateAll(incomeArray)
	fmt.Printf("总共收入是: %.2f \n ", totalAmount)

	//接口对象转型第一种方式
	var shape1 Shape = Juxing{10, 20}
	if instance, ok := shape1.(Juxing); ok {
		fmt.Printf("这个是矩形 , area 是 : %.2f \n ", instance.area())
	} else if instance, ok := shape1.(Yuanxing); ok {
		fmt.Printf("这个是圆形 , area 是 : %.2f \n ", instance.area())
	}

	//接口对象转型第2种方式
	switch instance := shape1.(type) {
	case Yuanxing:
		fmt.Printf("这个是圆形 , area 是 : %.2f \n ", instance.area())
	case Juxing:
		fmt.Printf("这个是矩形 , area 是 : %.2f \n ", instance.area())
	}

}

func (a *AndroidPhone) call() {
	fmt.Printf("我是%s手机 \n", a.name)
}

func (i Iphone) call() {
	fmt.Printf("我是%s手机 \n ", i.name)
}

func (d Duck) sayHello() {
	fmt.Printf("%s 正在打招呼 \n", d.name)
}

func (p Person1) sayHello() {
	fmt.Printf("%s 正在打招呼 \n", p.name)
}

func (f FixProject) printProjectName() string {
	return f.projectName
}

func (f FixProject) calculate() float64 {
	return f.amount
}
func (t TimeProject) printProjectName() string {
	return t.projectName
}

func (t TimeProject) calculate() float64 {
	return t.amount
}

func calculateAll(incomeArray []Income) float64 {
	totalAmount := 0.0
	for _, income := range incomeArray {
		fmt.Printf("项目名称: %s , 金额 %.2f \n", income.printProjectName(), income.calculate())
		totalAmount += income.calculate()
	}

	return totalAmount
}

func (j Juxing) area() float64 {
	return j.chang * j.kuan
}
func (y Yuanxing) area() float64 {
	return y.banjing * y.banjing
}
